home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / decoyz.zip / DECOY.QC < prev    next >
Text File  |  1996-09-09  |  15KB  |  497 lines

  1. /*
  2. ==============================================================================
  3.                             
  4. DECOY AI
  5.  
  6. ==============================================================================
  7. */
  8.  
  9. // Prototypes
  10.  
  11.  
  12.  
  13. void    ()                                              decoy_attack;
  14. float   ()                                              DecoyFindTarget;
  15. void    ()                                              decoy_ai_stand;
  16. void    ()                                              decoy_pain;
  17. void    ()                                              decoy_die;
  18. void    ()                                              DecoySightSound;
  19. void    ()                                              DecoyFoundTarget;
  20. void    ()                                              DecoyHuntTarget;
  21. void    ()                                              decoy_ai_turn;
  22. void    ()                                              decoy_ai_walk;
  23. void    ()                                              decoy_ai_run;
  24. void    (void () thinkst)                               DecoyCheckRefire;
  25. void    (entity decoy)                                  DecoyDestroy;
  26. void    (entity decoy)                                  DecoyDeactivate;
  27. void    ()                                              decoytouch;
  28.  
  29. void    (entity aunit)                  DecoyCreate;
  30. entity  ()                              SelectSpawnPoint;
  31. void    (vector org)                     spawn_tfog;
  32.  
  33.  
  34. // Frame macros
  35.  
  36. $cd /raid/quake/id1/models/player_4
  37. $origin 0 -6 24
  38. $base base              
  39. $skin skin
  40.  
  41. $frame axrun1 axrun2 axrun3 axrun4 axrun5 axrun6
  42. $frame rockrun1 rockrun2 rockrun3 rockrun4 rockrun5 rockrun6
  43.  
  44. $frame stand1 stand2 stand3 stand4 stand5
  45. $frame axstnd1 axstnd2 axstnd3 axstnd4 axstnd5 axstnd6
  46. $frame axstnd7 axstnd8 axstnd9 axstnd10 axstnd11 axstnd12
  47.  
  48. $frame axpain1 axpain2 axpain3 axpain4 axpain5 axpain6
  49. $frame pain1 pain2 pain3 pain4 pain5 pain6
  50.  
  51.  
  52. $frame axdeth1 axdeth2 axdeth3 axdeth4 axdeth5 axdeth6
  53. $frame axdeth7 axdeth8 axdeth9
  54.  
  55. $frame deatha1 deatha2 deatha3 deatha4 deatha5 deatha6 deatha7 deatha8
  56. $frame deatha9 deatha10 deatha11
  57.  
  58. $frame deathb1 deathb2 deathb3 deathb4 deathb5 deathb6 deathb7 deathb8
  59. $frame deathb9
  60.  
  61. $frame deathc1 deathc2 deathc3 deathc4 deathc5 deathc6 deathc7 deathc8
  62. $frame deathc9 deathc10 deathc11 deathc12 deathc13 deathc14 deathc15
  63.  
  64. $frame deathd1 deathd2 deathd3 deathd4 deathd5 deathd6 deathd7
  65. $frame deathd8 deathd9
  66.  
  67. $frame deathe1 deathe2 deathe3 deathe4 deathe5 deathe6 deathe7
  68. $frame deathe8 deathe9
  69.  
  70. $frame nailatt1 nailatt2
  71.  
  72. $frame light1 light2
  73.  
  74. $frame rockatt1 rockatt2 rockatt3 rockatt4 rockatt5 rockatt6
  75.  
  76. $frame shotatt1 shotatt2 shotatt3 shotatt4 shotatt5 shotatt6
  77.  
  78. $frame axatt1 axatt2 axatt3 axatt4 axatt5 axatt6
  79.  
  80. $frame axattb1 axattb2 axattb3 axattb4 axattb5 axattb6
  81.  
  82. $frame axattc1 axattc2 axattc3 axattc4 axattc5 axattc6
  83.  
  84. $frame axattd1 axattd2 axattd3 axattd4 axattd5 axattd6
  85.  
  86.  
  87. void()  decoy_stand1      =[      $stand1,        decoy_stand2      ] {decoy_ai_stand();};
  88. void()  decoy_stand2      =[      $stand2,        decoy_stand3      ] {decoy_ai_stand();};
  89. void()  decoy_stand3      =[      $stand3,        decoy_stand4      ] {decoy_ai_stand();};
  90. void()  decoy_stand4      =[      $stand4,        decoy_stand5      ] {decoy_ai_stand();};
  91. void()  decoy_stand5      =[      $stand5,        decoy_stand1      ] {decoy_ai_stand();};
  92.  
  93.  
  94.  
  95. void()  decoy_walk1       =[      $rockrun1 ,        decoy_walk2       ]{decoy_ai_walk();};
  96. void()  decoy_walk2       =[      $rockrun2 ,        decoy_walk3       ] {decoy_ai_walk();};
  97. void()  decoy_walk3       =[      $rockrun3 ,        decoy_walk4       ] {decoy_ai_walk();};
  98. void()  decoy_walk4       =[      $rockrun4 ,        decoy_walk5       ] {decoy_ai_walk();};
  99. void()  decoy_walk5       =[      $rockrun5 ,        decoy_walk6       ] {decoy_ai_walk();};
  100. void()  decoy_walk6       =[      $rockrun6 ,        decoy_walk1       ] {decoy_ai_walk();};
  101.  
  102. void()  decoy_run1        =[      $rockrun1  ,        decoy_run2        ]{decoy_ai_run();};
  103. void()  decoy_run2        =[      $rockrun2  ,        decoy_run3        ] {decoy_ai_run();};
  104. void()  decoy_run3        =[      $rockrun3  ,        decoy_run4        ] {decoy_ai_run();};
  105. void()  decoy_run4        =[      $rockrun4  ,        decoy_run5        ] {decoy_ai_run();};
  106. void()  decoy_run5        =[      $rockrun5  ,        decoy_run6        ] {decoy_ai_run();};
  107. void()  decoy_run6        =[      $rockrun6  ,        decoy_run1        ] {decoy_ai_run();};
  108.  
  109. void()  decoy_atk1        =[      $shotatt1,       decoy_atk2        ] {ai_face();};
  110. void()  decoy_atk2        =[      $shotatt2,       decoy_atk3        ] {decoy_attack();};
  111. void()  decoy_atk3        =[      $shotatt3,       decoy_atk4        ] {ai_face();};
  112. void()  decoy_atk4        =[      $shotatt4,       decoy_atk5        ] {decoy_attack();};
  113. void()  decoy_atk5        =[      $shotatt5,       decoy_atk6        ] {ai_face();};
  114. void()  decoy_atk6        =[      $shotatt6,       decoy_atk1        ] 
  115. {
  116.     ai_face();
  117.     DecoyCheckRefire (decoy_atk1);
  118. };
  119.  
  120. void()  decoy_paina1      =[      $pain1,        decoy_paina2      ] {decoy_pain();};
  121. void()  decoy_paina2      =[      $pain2,        decoy_paina3      ] {};
  122. void()  decoy_paina3      =[      $pain3,        decoy_paina4      ] {};
  123. void()  decoy_paina4      =[      $pain4,        decoy_paina5      ] {};
  124. void()  decoy_paina5      =[      $pain5,        decoy_paina6      ] {};
  125. void()  decoy_paina6      =[      $pain6,        decoy_run1        ] {};
  126.  
  127. void()  decoy_die1        =[      $deatha1,        decoy_die2        ] {decoy_die();};
  128. void()  decoy_die2        =[      $deatha2,        decoy_die3        ] {};
  129. void()  decoy_die3        =[      $deatha3,        decoy_die4        ] {};
  130. void()  decoy_die4        =[      $deatha4,        decoy_die5        ] {ai_forward(14);};
  131. void()  decoy_die5        =[      $deatha5,        decoy_die6        ] {ai_forward(2);};
  132. void()  decoy_die6        =[      $deatha6,        decoy_die7        ] {};
  133. void()  decoy_die7        =[      $deatha7,        decoy_die8        ] {};
  134. void()  decoy_die8        =[      $deatha8,        decoy_die9        ] {};
  135. void()  decoy_die9        =[      $deatha9,        decoy_die10       ] {ai_forward(3);};
  136. void()  decoy_die10       =[      $deatha10,       decoy_die11       ] {};
  137. void()  decoy_die11       =[      $deatha11,       decoy_die11       ] {DecoyDestroy(self);};
  138.  
  139.  
  140. float() DecoyFindTarget =
  141. {
  142.     local entity head, selected;
  143.     local float dist;
  144.     dist = 1500;    // awareness radius of decoy, increasing it slows down game
  145.     selected = world;
  146.  
  147.     head = findradius(self.origin, 1500);
  148.     while(head)
  149.     {
  150.         if((!(head.flags & FL_NOTARGET) && 
  151.             (!(head.items & IT_INVISIBILITY)))  
  152.             &&
  153.             ((head.flags & FL_CLIENT) 
  154.             || (head.flags & FL_MONSTER)))
  155.         if ((head.health > 1) && (head != self))
  156.         if (head != self.maker)
  157.         if (visible(head))
  158.         if (trace_plane_dist < dist)
  159.         if ((head.health > 0) && (head !=self))
  160.            {
  161.             selected = head;
  162.             dist = trace_plane_dist;
  163.            }
  164.         head = head.chain;
  165.     }
  166.     self.enemy = selected;
  167.         
  168.     if (self.enemy == world)
  169.         return FALSE;
  170.         
  171.     else
  172.     {
  173.         self.oldenemy=self.enemy; 
  174.         DecoyFoundTarget();
  175.         sprint(self.maker, "Decoy Msg: Enemy sighted.\n");
  176.         return TRUE;
  177.     }
  178. };
  179.  
  180. //=============================================================
  181. // decoy_ai_stand - decoy stands in place until target acquired,
  182. // and starts to walk if pausetime has expired
  183. //=============================================================
  184. void() decoy_ai_stand =
  185. {
  186.     
  187.     if (DecoyFindTarget ())
  188.         return;
  189.     
  190.     if (time > self.pausetime)
  191.     {
  192.         self.th_walk ();
  193.         return;
  194.     }
  195. };
  196.  
  197.  
  198. //=============================================================
  199. // decoy_ai_walk - decoy is walking, looking for enemies
  200. //=============================================================
  201. void() decoy_ai_walk =
  202. {
  203.     if (DecoyFindTarget ())
  204.         return;
  205. };
  206.  
  207. //=============================================================
  208. // decoy_pain
  209. //=============================================================
  210. void()     decoy_pain =
  211. {      
  212.     local float r;
  213.     r = random ();
  214.     
  215.     if (r < 0.2)
  216.        sound (self, CHAN_VOICE, "player/pain1.wav", 1, ATTN_NORM);
  217.     else if (r < 0.3)
  218.        sound (self, CHAN_VOICE, "player/pain2.wav", 1, ATTN_NORM);
  219.     else if (r < 0.5)
  220.        sound (self, CHAN_VOICE, "player/pain3.wav", 1, ATTN_NORM);
  221.     else if (r < 0.7)
  222.        sound (self, CHAN_VOICE, "player/pain4.wav", 1, ATTN_NORM);
  223.     else if (r < 0.8)
  224.        sound (self, CHAN_VOICE, "player/pain5.wav", 1, ATTN_NORM);
  225.     else
  226.        sound (self, CHAN_VOICE, "player/pain6.wav", 1, ATTN_NORM);
  227.     
  228. };
  229.  
  230. //=============================================================
  231. // decoy_die
  232. //=============================================================
  233. void() decoy_die =
  234. {
  235.     sound (self, CHAN_VOICE, "player/h2odeath.wav", 1, ATTN_NORM);
  236.  
  237.  
  238. };
  239.  
  240.  
  241. //=============================================================
  242. // DecoySightSound
  243. //=============================================================
  244. void() DecoySightSound =
  245. {
  246.     local float     rsnd;
  247.  
  248.     rsnd = rint(random() * 3);                      
  249.     if (rsnd == 1)
  250.         sound (self, CHAN_VOICE, "weapons/lock4.wav", 1, ATTN_NORM);
  251.     else if (rsnd == 2)
  252.         sound (self, CHAN_VOICE, "weapons/pkup.wav", 1, ATTN_NORM);
  253.     else if (rsnd == 0)
  254.         sound (self, CHAN_VOICE, "weapons/grendade.wav", 1, ATTN_NORM);
  255.     else
  256.         sound (self, CHAN_VOICE, "weapons/spike2.wav", 1, ATTN_NORM);
  257.     
  258. };
  259.  
  260.  
  261. //=============================================================
  262. // decoyHuntTarget
  263. //=============================================================
  264. void() DecoyHuntTarget =
  265. {
  266.     self.goalentity = self.enemy;
  267.     self.think = self.th_run;
  268.     self.ideal_yaw = vectoyaw(self.enemy.origin - self.origin);
  269.     self.nextthink = time + 0.1;
  270.     SUB_AttackFinished (0.1);       // wait a while before first attack
  271. };
  272.  
  273.  
  274. //=============================================================
  275. // DecoyFoundTarget
  276. //=============================================================
  277. void() DecoyFoundTarget =
  278. {
  279.     local float f_dist;
  280.     local string s_dist;
  281.     f_dist = vlen (self.enemy.origin - self.origin);
  282.     s_dist = ftos (f_dist);
  283.  
  284.     
  285.     DecoySightSound ();
  286.     DecoyHuntTarget ();
  287. };
  288.  
  289.  
  290.  
  291. //=============================================================
  292. // decoy_ai_turn - turn towards ideal_yaw if no enemy sighted
  293. //=============================================================
  294. void() decoy_ai_turn =
  295. {
  296.     if (DecoyFindTarget ())
  297.         return;
  298.     
  299.     ChangeYaw ();
  300. };
  301.  
  302.  
  303. //=============================================================
  304. // decoy_ai_run - still needs a little work
  305. //=============================================================
  306. void() decoy_ai_run =
  307. {
  308.     local   vector  delta;
  309.     local   float   axis;
  310.     local   float   direct, ang_rint, ang_floor, ang_ceil;
  311.         
  312.  
  313.     if (self.enemy.health <= 0)
  314.     {
  315.         self.enemy = world;
  316.         if (self.oldenemy.health > 0)   
  317.         {                               
  318.             self.enemy = self.oldenemy;
  319.             DecoyHuntTarget ();          
  320.         }
  321.         else
  322.         {
  323.             if (DecoyFindTarget())
  324.                 return;
  325.             else
  326.             {
  327.                 self.th_stand ();
  328.                 return;
  329.             }
  330.         }
  331.     }
  332.  
  333.     
  334.     enemy_vis = visible(self.enemy);
  335.     if (enemy_vis)
  336.         self.search_time = time + 5;
  337.  
  338.     enemy_infront = infront(self.enemy);
  339.     enemy_range = range(self.enemy);
  340.     enemy_yaw = vectoyaw(self.enemy.origin - self.origin);
  341.     
  342.     
  343.     if (CheckAnyAttack ())
  344.         return;                                 // beginning an attack
  345.         
  346.     if (self.attack_state == AS_SLIDING)
  347.     {
  348.         ai_run_slide ();
  349.         return;
  350.     }
  351.         
  352.     };
  353.  
  354.  
  355. //=============================================================
  356. // DecoyCheckRefire
  357. //=============================================================
  358. void (void () thinkst) DecoyCheckRefire =
  359. {
  360.     
  361.     if (!visible (self.enemy) || (self.enemy.health <= 0))        
  362.         {
  363.         if (self.enemy.health <= 0)
  364.          {
  365.         if (self.oldenemy.health>0) //if oldenemy still kickin
  366.         self.enemy=self.oldenemy;   //change to old enemy  
  367.         HuntTarget();               //Hunt him down
  368.         }
  369.         return;
  370.         } 
  371.         self.think = thinkst;
  372. };
  373.  
  374.  
  375. //=============================================================
  376. // DecoyActivate - Activates the decoy
  377. //=============================================================
  378. void (entity aunit) DecoyCreate =
  379. {
  380.  
  381.     local entity    newdecoy;
  382.     
  383.     newdecoy = spawn();
  384.     newdecoy.solid = SOLID_SLIDEBOX;
  385.     newdecoy.movetype = MOVETYPE_STEP;
  386.  
  387.     newdecoy.angles = self.angles;
  388.     newdecoy.classname = "decoy";
  389.     newdecoy.maker = self;
  390.     newdecoy.skin = self.skin;    
  391.     newdecoy.health = 100;              
  392.     newdecoy.max_health = 100;          
  393.     newdecoy.takedamage = DAMAGE_AIM;
  394.     newdecoy.goalentity = self;
  395.     newdecoy.movetarget = self;
  396.     newdecoy.pausetime = time + 2;
  397.     newdecoy.ideal_yaw = newdecoy.angles * '0 1 0';
  398.     newdecoy.yaw_speed = 90;
  399.     newdecoy.weapon = 2;
  400.     newdecoy.ammo_shells = 100;
  401.     newdecoy.view_ofs = '0 0 25';
  402.     newdecoy.touch = decoytouch;
  403.     newdecoy.th_stand = decoy_stand1;
  404.     newdecoy.th_walk = decoy_walk1;
  405.     newdecoy.th_run = decoy_run1;
  406.     newdecoy.th_pain = decoy_paina1;
  407.     newdecoy.th_die = decoy_die1;
  408.     newdecoy.th_missile = decoy_atk1;
  409.     setmodel (newdecoy, "progs/player.mdl");
  410.     setsize (newdecoy, '-16 -16 -24', '16 16 40');
  411.  
  412.     setorigin(newdecoy, aunit.origin + '0 0 50');
  413.     remove(aunit);
  414.         
  415.     spawn_tfog (newdecoy.origin);
  416.     bprint("New Decoy Created \n");
  417.     
  418.     newdecoy.nextthink = time + 0.1;
  419.     newdecoy.think = newdecoy.th_stand;
  420. };
  421.     
  422.  
  423. //=============================================================
  424. // DecoyDestroy - Decoy destroys itself
  425. //=============================================================
  426. void (entity decoy) DecoyDestroy =
  427. {
  428.         decoy.solid = SOLID_NOT;
  429.         T_RadiusDamage(decoy, world, 150, world);
  430.     WriteByte(MSG_BROADCAST, SVC_TEMPENTITY);
  431.     WriteByte(MSG_BROADCAST, TE_EXPLOSION);
  432.         WriteCoord(MSG_BROADCAST, decoy.origin_x);
  433.         WriteCoord(MSG_BROADCAST, decoy.origin_y);
  434.         WriteCoord(MSG_BROADCAST, decoy.origin_z);
  435.         setmodel(decoy, "progs/s_explod.spr");
  436.         remove(decoy);
  437.         sprint(decoy.maker, "Decoy detonated.\n");
  438. };
  439.  
  440. void (entity decoy) DecoyDeactivate =
  441. {
  442.   decoy.maker.currentammo = decoy.maker.ammo_rockets = decoy.maker.ammo_rockets + 1;
  443.   decoy.maker.currentammo = decoy.maker.ammo_cells = decoy.maker.ammo_cells + 1;
  444.   remove(decoy);
  445.   sprint(decoy.maker, "Decoy switched off.\n");
  446.   sprint(decoy.maker, "Ammo retrieved.\n");
  447. };
  448.  
  449. void() decoytouch =
  450. {            
  451.     if (other == world) 
  452.          return; 
  453.     if (self.maker == other)
  454.          return;
  455.         if (other.classname == "spike")
  456.              return;    
  457.         if (other.classname == "grenade")
  458.              return;
  459.     if (other.classname == "dactivator")
  460.          return;    
  461.     if (other.movetype == MOVETYPE_FLYMISSILE)
  462.          return;    
  463.  
  464.  
  465.         DecoyDestroy(self);        
  466. };
  467.  
  468.  
  469. void() decoy_FireShotgun =
  470. {
  471.     local vector dir;
  472.     sound (self, CHAN_VOICE, "weapons/guncock.wav", 1, ATTN_NORM);
  473.     self.effects = self.effects | EF_MUZZLEFLASH;
  474.     dir = aim (self, 100000);
  475. //      FireBullets (6, dir, '0.04 0.04 0');
  476. };
  477.  
  478.  
  479. /*
  480. ==========================
  481. decoy_attack - fires weapon
  482. ==========================
  483. */
  484. void() decoy_attack =
  485. {
  486.     local   float   r;
  487.  
  488.     if (!visible (self.enemy) || (self.enemy.health <= 0))
  489.         return;
  490.  
  491.     
  492.     makevectors     (self.angles);     
  493.     
  494.     decoy_FireShotgun ();
  495.     
  496. };
  497.